package com.web.exiaodao.remote.service.impl;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.web.exiaodao.business.constant.JConstant;
import com.web.webstart.base.util.shortmsg.YuntongxunSmsUtil;
import com.web.exiaodao.business.entity.*;
import com.web.exiaodao.business.repository.*;
import com.web.exiaodao.remote.service.*;
import com.web.exiaodao.remote.vo.*;
import com.web.webstart.base.constant.XaConstant;
import com.web.webstart.base.exception.BusinessException;
import com.web.webstart.base.service.impl.BaseService;
import com.web.webstart.base.util.CollectionUtils;
import com.web.webstart.base.util.DateUtils;
import com.web.webstart.base.util.XaUtil;
import com.web.webstart.base.util.jpa.DynamicSpecifications;
import com.web.webstart.base.util.jpa.SearchFilter;
import com.web.webstart.base.util.jpa.SearchFilter.Operator;
import com.web.webstart.base.util.jpa.WebUitl;
import com.web.webstart.base.util.result.XaResult;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

import static com.web.webstart.base.util.XaUtil.Sql;

/**
 * @author: zhangl
 * @times: 2016-11-03 10:54:30
 * 类的说明：前端APIOrder接口实现类
 **/
@Service("ApiOrderService")
@Transactional(readOnly = false)
public class ApiOrderServiceImpl extends BaseService<Order> implements ApiOrderService {

    private static final Logger LOGGER = Logger.getLogger(ApiOrderServiceImpl.class);

    @Autowired
    ApiUserService userService;

    @Autowired
    UserRepository repository;

    @Autowired
    ApiConfigurationTableService configurationTableService;

    @Autowired
    OrderRepository orderRepository;

    @Autowired
    OrderDetailRepository orderDetailRepository;

    @Autowired
    private ApiShopService shopService;
    @Autowired
    private ShopRepository shopRepository;
    @Autowired
    private ShopCarRepository shopCarRepository;

    @Autowired
    ApiMakeMoneyTableService makeMoneyTableService;

    @Autowired
    ApiServiceNurseTrainingService nurseTrainingService;
    @Autowired
    ApiServiceCommonService serviceCommonService;
    @Autowired
    ApiServiceDomesticNursingService domesticNursingService;
    @Autowired
    ApiInsHotelRoomsTableService insHotelRoomsTableService;
    @Autowired
    ApiInstitutionService institutionService;
    @Autowired
    private ApiExchangeProductsService exchangeProductsService;
    @Autowired
    private ApiShopStandardNameService shopStandardNameService;

    @Autowired
    ApiArtInformationService informationService;//作者表
    @Autowired
    ApiAutherWorksTableService autherWorksTableService;//作品
    @Autowired
    ApiTravelTableService travelTableService;

    @Autowired
    private ApiWalletTradeRecordService walletTradeRecordService;

    @Override
    public XaResult<OrderVo> findOne(Long tId) throws BusinessException {
        throw new BusinessException(XaConstant.Message.error_method_no_impl);
    }


    @Override
    public XaResult<List<OrderVo>> findListNEStatusByFilter(
            Integer status, Map<String, Object> filterParams, Pageable pageable)
            throws BusinessException {
        throw new BusinessException(XaConstant.Message.error_method_no_impl);
    }


    /**
     * 删除订单
     *
     * @param modelIds 删除的订单号
     * @param status   {@link JConstant.OrderStatus} 只有交易关闭和交易完成的订单才能删除
     * @return
     * @throws BusinessException
     */
    @Override
    public XaResult<OrderVo> multiOperate(String modelIds,
                                          Integer status) throws BusinessException {
        XaResult<OrderVo> xr = new XaResult<>();
        if (status == null) {
            status = XaConstant.Status.delete;
        }
        if (modelIds != null) {
            String[] ids = modelIds.split(JConstant.SYMBOL_DOT);
            for (String orderNo : ids) {
                Order obj = orderRepository.findByOrderNoAndStatusNot(orderNo, status);
                if (XaUtil.isNotEmpty(obj)) {
                    if (Integer.parseInt(obj.getOrderState()) == JConstant.OrderStatus.UN_COMMENT ||
                            Integer.parseInt(obj.getOrderState()) == JConstant.OrderStatus.SUCCES_TRADE ||
                            Integer.parseInt(obj.getOrderState()) == JConstant.OrderStatus.CLOSE_TRADE) {
                        if (obj.getRefundStatus() == null) {
                            obj.setStatus(status);
                            obj = orderRepository.save(obj);
                            xr.setObject(JSON.parseObject(JSON.toJSONString(obj), OrderVo.class));
                            xr.getObject().setId(obj.getId());
                        } else {
                            xr.error("订单不能删除(你已经审核退货/退款)!");
                        }
                    } else {
                        xr.error("订单不能删除(状态不允许)!");
                    }
                }
            }
        }
        LOGGER.info("更改数据状态----->Order");
        return xr;
    }

    /**
     * 创建服务类订单
     *
     * @param order
     * @return
     * @throws BusinessException
     */
    @Override
    public XaResult<OrderVo> createModel(Order order)
            throws BusinessException {
        throw new BusinessException(XaConstant.Message.error_method_no_impl);
    }

    /**
     * 保存Order信息
     *
     * @param model
     * @return
     * @throws BusinessException
     */
    @Transactional(rollbackFor = Exception.class)
    public XaResult<OrderVo> updateModel(Order model) throws BusinessException {
        Order obj = null;
        if (XaUtil.isNotEmpty(model.getId())) {
            obj = orderRepository.findOne(model.getId());
        } else {
            obj = new Order();
        }
        obj.setUserId(XaUtil.isNotEmpty(model.getUserId()) ? model.getUserId() : obj.getUserId());
        obj.setOrderNo(XaUtil.isNotEmpty(model.getOrderNo()) ? model.getOrderNo() : obj.getOrderNo());
        obj.setOrder_PAY_DateTime(XaUtil.isNotEmpty(model.getOrder_PAY_DateTime()) ? model.getOrder_PAY_DateTime() : obj.getOrder_PAY_DateTime());
        obj.setOrder_DeliverGoods_DateTime(XaUtil.isNotEmpty(model.getOrder_DeliverGoods_DateTime()) ? model.getOrder_DeliverGoods_DateTime() : obj.getOrder_DeliverGoods_DateTime());
        obj.setOrder_Sucess_DateTime(XaUtil.isNotEmpty(model.getOrder_Sucess_DateTime()) ? model.getOrder_Sucess_DateTime() : obj.getOrder_Sucess_DateTime());
        obj.setOrderReceivingDatetime(XaUtil.isNotEmpty(model.getOrderReceivingDatetime()) ? model.getOrderReceivingDatetime() : obj.getOrderReceivingDatetime());
        obj.setOrder_Dead_DateTime(XaUtil.isNotEmpty(model.getOrder_Dead_DateTime()) ? model.getOrder_Dead_DateTime() : obj.getOrder_Dead_DateTime());
        obj.setOrderState(XaUtil.isNotEmpty(model.getOrderState()) ? model.getOrderState() : obj.getOrderState());
        obj.setPaymentKind(XaUtil.isNotEmpty(model.getPaymentKind()) ? model.getPaymentKind() : obj.getPaymentKind());
        obj.setOrderTotalPirce(XaUtil.isNotEmpty(model.getOrderTotalPirce()) ? model.getOrderTotalPirce() : obj.getOrderTotalPirce());
        obj.setPostage(XaUtil.isNotEmpty(model.getPostage()) ? model.getPostage() : obj.getPostage());
        obj.setDeducted_money(XaUtil.isNotEmpty(model.getDeducted_money()) ? model.getDeducted_money() : obj.getDeducted_money());
        obj.setExpressCompany(XaUtil.isNotEmpty(model.getExpressCompany()) ? model.getExpressCompany() : obj.getExpressCompany());
        obj.setExpressNumber(XaUtil.isNotEmpty(model.getExpressNumber()) ? model.getExpressNumber() : obj.getExpressNumber());
        obj.setOrderVilidaty(XaUtil.isNotEmpty(model.getOrderVilidaty()) ? model.getOrderVilidaty() : obj.getOrderVilidaty());
        obj.setOrderType(XaUtil.isNotEmpty(model.getOrderType()) ? model.getOrderType() : obj.getOrderType());
        obj.setService_object_id(XaUtil.isNotEmpty(model.getService_object_id()) ? model.getService_object_id() : obj.getService_object_id());
        obj.setService_num(XaUtil.isNotEmpty(model.getService_num()) ? model.getService_num() : obj.getService_num());
        obj.setService_price(XaUtil.isNotEmpty(model.getService_price()) ? model.getService_price() : obj.getService_price());
        obj.setService_userName(XaUtil.isNotEmpty(model.getService_userName()) ? model.getService_userName() : obj.getService_userName());
        obj.setService_phone(XaUtil.isNotEmpty(model.getService_phone()) ? model.getService_phone() : obj.getService_phone());
        obj.setService_idCard(XaUtil.isNotEmpty(model.getService_idCard()) ? model.getService_idCard() : obj.getService_idCard());
        obj.setService_appointment_time(XaUtil.isNotEmpty(model.getService_appointment_time()) ? model.getService_appointment_time() : obj.getService_appointment_time());
        obj.setHourse_checkinTime(XaUtil.isNotEmpty(model.getHourse_checkinTime()) ? model.getHourse_checkinTime() : obj.getHourse_checkinTime());
        obj.setHourse_checkin_duration(XaUtil.isNotEmpty(model.getHourse_checkin_duration()) ? model.getHourse_checkin_duration() : obj.getHourse_checkin_duration());
        obj.setHourse_checkin_duration_unit(XaUtil.isNotEmpty(model.getHourse_checkin_duration_unit()) ? model.getHourse_checkin_duration_unit() : obj.getHourse_checkin_duration_unit());
        obj.setInsVisitPurpose(XaUtil.isNotEmpty(model.getInsVisitPurpose()) ? model.getInsVisitPurpose() : obj.getInsVisitPurpose());
        obj.setInsVisitCompany(XaUtil.isNotEmpty(model.getInsVisitCompany()) ? model.getInsVisitCompany() : obj.getInsVisitCompany());
        obj.setGoodsTotalPrices(XaUtil.isNotEmpty(model.getGoodsTotalPrices()) ? model.getGoodsTotalPrices() : obj.getGoodsTotalPrices());
        obj.setLeaveMsg(XaUtil.isNotEmpty(model.getLeaveMsg()) ? model.getLeaveMsg() : obj.getLeaveMsg());
        obj.setAddressId(XaUtil.isNotEmpty(model.getAddressId()) ? model.getAddressId() : obj.getAddressId());
        obj.setConsigneeName(XaUtil.isNotEmpty(model.getConsigneeName()) ? model.getConsigneeName() : obj.getConsigneeName());
        obj.setConsigneeTel(XaUtil.isNotEmpty(model.getConsigneeTel()) ? model.getConsigneeTel() : obj.getConsigneeTel());
        obj.setConsigneeAdress(XaUtil.isNotEmpty(model.getConsigneeAdress()) ? model.getConsigneeAdress() : obj.getConsigneeAdress());
        obj.setBillType(XaUtil.isNotEmpty(model.getBillType()) ? model.getBillType() : obj.getBillType());
        obj.setBillTitle(XaUtil.isNotEmpty(model.getBillTitle()) ? model.getBillTitle() : obj.getBillTitle());
        obj.setBillContent(XaUtil.isNotEmpty(model.getBillContent()) ? model.getBillContent() : obj.getBillContent());
        obj.setBillEtype(XaUtil.isNotEmpty(model.getBillEtype()) ? model.getBillEtype() : obj.getBillEtype());
        obj.setOfflinePrices(XaUtil.isNotEmpty(model.getOfflinePrices()) ? model.getOfflinePrices() : obj.getOfflinePrices());
        obj.setQueryId(XaUtil.isNotEmpty(model.getQueryId()) ? model.getQueryId() : obj.getQueryId());
        obj.setRefuOrderNo(XaUtil.isNotEmpty(model.getRefuOrderNo()) ? model.getRefuOrderNo() : obj.getRefuOrderNo());
        obj.setRefundStatus(XaUtil.isNotEmpty(model.getRefundStatus()) ? model.getRefundStatus() : obj.getRefundStatus());
        obj = orderRepository.save(obj);
        XaResult<OrderVo> xr = new XaResult<OrderVo>();
        xr.setObject(JSON.parseObject(JSON.toJSONString(obj), OrderVo.class));
        LOGGER.info("后台新增或编辑数据成功！");
        return xr;
    }


    /**
     * 创建服务类订单 or 兑换商品下单
     *
     * @param order
     * @return
     * @throws BusinessException
     */
    @Override
    public XaResult<OrderVo> saveSericeOrder(Order order) throws BusinessException {
        XaResult<OrderVo> xr = new XaResult<OrderVo>();
        //订单有效期，目前暂设12小时
        order.setOrderVilidaty(getOrderVilidatyDefault());

        //抵扣价格
        UserVo userVo = userService.findOne(order.getUserId()).getObject();
        double balanceCoin = userVo.getBalanceCoin();
        if (order.getDeducted_money().doubleValue() > balanceCoin) {
            xr.error("亲币不足,您的亲币余额:" + balanceCoin);
            return xr;
        }

        //扣除亲币
        if (order.getDeducted_money() > 0) {
            makeMoneyTableService.saveMakeMoneyRecord(order.getUserId(), JConstant.ConsumeOrMakeMoney.Consume, order.getDeducted_money(), JConstant.IntegralTypeEnum.CONSUME.getIndex());
        }

        OrderDetail orderDetail = new OrderDetail();

        Double allMoney = new Double(0);//全额的钱；（机构买卡；旅游；艺术品）模块有

        switch (Integer.parseInt(order.getOrderType())) {
            case JConstant.Order_CommentType.SERVICE_NURSE_TRANING://护理培训|培训义工  有库存;有失效时间
            {
                ServiceNurseTrainingVo nurseTrainingVO = nurseTrainingService.findOne(order.getService_object_id()).getObject();

                //报价截止时间
                Date startTime = DateUtils.formatStr(nurseTrainingVO.getOrderStartTime(), DateUtils.YYYYMMDDHHMM);
                Date endTime = DateUtils.formatStr(nurseTrainingVO.getOrderEndTime(), DateUtils.YYYYMMDDHHMM);
                Date nowDate = new Date();
                if (endTime == null) {
                    xr.error("日期格式转换错误{" + nurseTrainingVO.getOrderEndTime() + "}，应为{yyyy-MM-dd HH:mm}");
                    return xr;
                }
                if (new Date().compareTo(startTime) != 1) {
                    xr.error("报名还没开始");
                    return xr;
                }
                if (endTime.compareTo(new Date()) < 0) {
                    xr.error("报名时间已经截止,可以联系客服");
                    return xr;
                }
                int inventory = nurseTrainingVO.getQuantityInventory();
                if (order.getService_num().intValue() > inventory) {
                    xr.error("名额不足,还剩余:" + inventory + "个名额");
                    return xr;
                }
                if (nurseTrainingVO.getPrice().doubleValue() != order.getService_price()) {
                    xr.error("服务单价不正确,应:" + nurseTrainingVO.getPrice() + "");
                    return xr;
                }

                nurseTrainingVO.setQuantityInventory(nurseTrainingVO.getQuantityInventory() - order.getService_num().intValue());
                nurseTrainingService.updateModel(JSON.parseObject(JSON.toJSONString(nurseTrainingVO), ServiceNurseTraining.class));

                orderDetail = new OrderDetail(
                        order.getService_object_id() + "",
                        nurseTrainingVO.getNurseTraining_Name(),
                        nurseTrainingVO.getNurseTraining_url(),
                        nurseTrainingVO.getPrice(),
                        order.getService_num(),
                        ""
                );
            }
            break;
            case JConstant.Order_CommentType.HOURSE: {
                //  51:住--------------
                XaResult<InsHotelRoomsTableVo> insRoomsXA = insHotelRoomsTableService.findOne(order.getService_object_id());
                //库存处理
                //// TODO: 2016/12/28 酒店
//                int inventory = insRoomsXA.getObject().getHotelRooms_Inventory();
//                if (order.getService_num().intValue() > inventory) {
//                    xr.error("房源不足");
//                    return xr;
//                }
//                insRoomsXA.getObject().setHotelRooms_Inventory(inventory - order.getService_num().intValue());
//                InsHotelRoomsTableVo vo = insHotelRoomsTableService.updateModel(JSON.parseObject(JSON.toJSONString(insRoomsXA.getObject()), InsHotelRoomsTable.class)).getObject();

                InsHotelRoomsTableVo vo = insRoomsXA.getObject();
                vo = insHotelRoomsTableService.findOne(vo.getId()).getObject();


                if (vo.getIsSellByCard()) {
                    orderDetail = new OrderDetail(
                            order.getService_object_id() + "",
                            vo.getHotelRooms_Name(),
                            XaUtil.isEmpty(vo.getHotelRooms_bannerList()) ? "" : vo.getHotelRooms_bannerList().get(0),
                            vo.getBookPrice(),//预订价格
                            vo.getHotelRooms_Price(),//全额
                            order.getService_num(),
                            ""
                    );
                } else {
                    orderDetail = new OrderDetail(
                            order.getService_object_id() + "",
                            vo.getHotelRooms_Name(),
                            XaUtil.isEmpty(vo.getHotelRooms_bannerList()) ? "" : vo.getHotelRooms_bannerList().get(0),
                            vo.getHotelRooms_Price(),//全额
                            order.getService_num(),
                            ""
                    );
                }

                if (vo.getIsSellByCard()) {
                    allMoney = vo.getHotelRooms_Price();//买卡的全额
                }
            }
            break;
            case JConstant.Order_CommentType.INSTIBUTION_VISITING: {
                //  52:机构参观--------------
                InstitutionVo vo = institutionService.findOne(order.getService_object_id()).getObject();

                orderDetail = new OrderDetail(
                        order.getService_object_id() + "",
                        vo.getInstitution_Name(),
                        vo.getInstitution_pic(),
                        vo.getInstitution_Price(),
                        order.getService_num(),
                        ""
                );
            }
            break;
            case JConstant.Order_CommentType.GOODS_EXCHANGE: {
                //  2:兑换商品--------------
                ExchangeProductsVo vo = exchangeProductsService.findOne(order.getService_object_id()).getObject();

                //库存处理
                if (vo.getInventory() <= 0) {
                    xr.error("兑换商品库存不足");
                    return xr;
                }

                //库存-1; 已经兑换数量+1
                vo.setExchangedNum(vo.getExchangedNum() + 1);//已经兑换数量
                vo.setInventory(vo.getExchangedNum() - 1);//库存
                exchangeProductsService.updateModel(JSON.parseObject(JSON.toJSONString(vo), ExchangeProducts.class));

                //兑换商品-直接变成已经支付状态
                order.setOrderState(JConstant.OrderStatus.SUCCES_TRADE + "");
                order.setOrder_Sucess_DateTime(DateUtils.getToDayStr());

                orderDetail = new OrderDetail(
                        order.getService_object_id() + "",
                        vo.getProductName(),
                        vo.getProductImg(),
                        Double.parseDouble(vo.getNeedCoins()), //price
                        order.getService_num(),//下单数量
                        ""
                );
            }
            break;
            case JConstant.Order_CommentType.TOUR: {
                //  53：旅游/游学--------------
                TravelTableVo vo = travelTableService.findOne(order.getService_object_id()).getObject();

                orderDetail = new OrderDetail(
                        order.getService_object_id() + "",
                        vo.getTravelItemName(),
                        vo.getTourImg(),
                        vo.getReservationPrice(),//预订价格
                        vo.getTravelItemPrice(),//全额
                        order.getService_num(),
                        ""
                );

                if (vo.getReservationPrice() != null && vo.getReservationPrice() != 0) {
                    allMoney = vo.getTravelItemPrice();//旅游抱团的全额
                }
            }
            break;
            case JConstant.Order_CommentType.ARTWORK: {
                //  3：玩 /达人/作品/艺术品
                AutherWorksTableVo vo = autherWorksTableService.findOne(order.getService_object_id()).getObject();

                orderDetail = new OrderDetail(
                        order.getService_object_id() + "",
                        vo.getWorksName(),
                        (XaUtil.isNotEmpty(vo.getWorksImgs1())) ? vo.getWorksImgs1().get(0) : "",
                        vo.getWorksDeposit(),//预订价格
                        vo.getWorksPrice(),//全额
                        order.getService_num(),
                        ""
                );

                //库存处理
                if (order.getService_num().intValue() > vo.getWorksInventory()) {
                    xr.error("库存不足");
                    return xr;
                }

                //库存-1
                vo.setWorksInventory(vo.getWorksInventory() - order.getService_num());//库存已经兑换数量
                vo = autherWorksTableService.updateModel(JSON.parseObject(JSON.toJSONString(vo), AutherWorksTable.class)).getObject();
                System.out.printf("");

                if (vo.getWorksDeposit() != null && vo.getWorksDeposit() != 0) {
                    allMoney = vo.getWorksPrice();//技术品的全额
                }
            }
            break;
        }


        //计算抵扣价格
        int coinNum = order.getDeducted_money();//用户抵扣的亲币数量
        ConfigurationTableVo configurationTableVo = configurationTableService.findLastOne().getObject();
        double deducetMonet = coinNum * 1.0f / configurationTableVo.getSignin_inance_expr_coin();


        //最终价格:单价*数量-亲币抵扣+邮费
        if (Integer.parseInt(order.getOrderType()) != JConstant.Order_CommentType.GOODS_EXCHANGE) {//兑换商品没有价格
            order.setGoodsTotalPrices(order.getService_num().intValue() * order.getService_price().doubleValue() * order.getHourse_checkin_duration());
            double finalPirce = order.getGoodsTotalPrices() - deducetMonet + order.getPostage().doubleValue();
            if (finalPirce != order.getOrderTotalPirce().doubleValue()) {
                xr.error("下单总价计算错误");
                return xr;
            }
            if (finalPirce < 0.01) {
                xr.error("商品至少支付0.01元");
                return xr;
            }
        } else {
            order.setGoodsTotalPrices(Double.parseDouble("0"));
            order.setOrderTotalPirce(Double.parseDouble("0"));
        }

        //计算：线下支付的价格=总金额-定金
        if (allMoney != null && allMoney != 0) {
            Double allMoneyCount = order.getService_num().intValue() * allMoney * order.getHourse_checkin_duration();
            double offlineprices = allMoneyCount - order.getGoodsTotalPrices();
            order.setOfflinePrices(offlineprices);//线下支付的价格
            LOGGER.info("线下支付的价格----->Order:" + offlineprices);
        } else {
            order.setOfflinePrices(null);
        }

        //订单默认状态:未支付
        if (Integer.parseInt(order.getOrderType()) != JConstant.Order_CommentType.HOURSE) {
            order.setHourse_checkin_duration(null);
            order.setHourse_checkin_duration_unit(null);
            order.setHourse_checkinTime(null);
        }

        //下订单
        Order obj = orderRepository.save(order);
        xr.setObject(JSON.parseObject(JSON.toJSONString(obj), OrderVo.class));
        xr.getObject().setId(obj.getId());

        //保存订单详情
        orderDetail.setOrderNo(obj.getOrderNo());
        orderDetailRepository.save(orderDetail);

        LOGGER.info("服务类订单,下单成功----->Order:" + obj.getOrderNo());
        return xr;
    }

    /**
     * 下单(普通商品)
     *
     * @param order
     * @return
     */
    @Override
    public XaResult<OrderVo> saveShopOrder(Order order, List<OrderDetailVo> details, String carIds) throws BusinessException {
        //0 校验购物车id是否存在,如果已经下单过 ,购物车id就被删除了
        //1:
        //订单有效期，目前暂设12小时
        //扣除亲币
        //处理库存
        //计算抵扣价格
        //2:
        //复制商品信息到订单详情表中
        //3:
        //如果是购物车下单，成功后清除购物车数据

        XaResult<OrderVo> xr = new XaResult<OrderVo>();

        //订单有效期，目前暂设12小时
        order.setOrderVilidaty(getOrderVilidatyDefault());

        //计算抵扣价格
        int coinNum = order.getDeducted_money();
        ConfigurationTableVo configurationTableVo = configurationTableService.findLastOne().getObject();
        double deducetMonet = coinNum * 1.0f / configurationTableVo.getSignin_inance_expr_coin();
        //最终价格:单价*数量-亲币抵扣+邮费
        double finalPirce = order.getGoodsTotalPrices() - deducetMonet + order.getPostage();
        BigDecimal b1 = new BigDecimal(finalPirce);
        //保留两位小数
        finalPirce = b1.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        {
            //商品最多可以抵扣的总额
            double disCountTempMoney = 0;
            for (int i = 0; i < details.size(); ++i) {
                OrderDetailVo detailVo = details.get(i);
                long num = detailVo.getProductNum();
                double disRate = detailVo.getShopDisCountRate();
                double productOrderPrice = detailVo.getProductOrderPrice();
                disCountTempMoney += num * disRate * productOrderPrice;
            }
            BigDecimal b3 = new BigDecimal(disCountTempMoney);
            disCountTempMoney = b3.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();

            if (deducetMonet > disCountTempMoney) {
                xr.error("商品最多可以抵扣" + disCountTempMoney + "钱");
                return xr;
            }
        }
        if (finalPirce < 0.01) {
            xr.error("商品至少支付0.01元");
            return xr;
        }

        //抵扣价格
        UserVo userVo = userService.findOne(order.getUserId()).getObject();
        double balanceCoin = userVo.getBalanceCoin();
        if (order.getDeducted_money() > balanceCoin) {
            xr.error("亲币数量不足,您的亲币数量为:" + (long) balanceCoin);
            return xr;
        }

        if (XaUtil.isNotEmpty(carIds)) {
            Iterable<ShopCar> shopCars = shopCarRepository.findAll(Arrays.asList(XaUtil.splitLong(carIds, JConstant.SYMBOL_DOT)));
            if (Lists.newArrayList(shopCars).size() != carIds.split(JConstant.SYMBOL_DOT).length) {
                xr.error("购物车商品请不要重复下单or商品信息和购物车信息不匹配!");
                return xr;
            }
        }

        //扣除亲币
        if (order.getDeducted_money() > 0) {
            makeMoneyTableService.saveMakeMoneyRecord(order.getUserId(), JConstant.ConsumeOrMakeMoney.Consume, order.getDeducted_money(), JConstant.IntegralTypeEnum.CONSUME.getIndex());
        }

        //查询所有商品的信息
        Set<String> params_set = new HashSet<>();
        for (OrderDetailVo obj : details) {
            String str = obj.getStandardValues();
            if (XaUtil.isNotEmpty(str)) {
                params_set.addAll(Arrays.asList(str.split(JConstant.SYMBOL_DOT)));
            }
        }
        //查询所有的规格
        List<ShopStandardVo> shopStandardVos = new ArrayList<>();
        XaResult<List<ShopStandardVo>> shopStandsXr = shopStandardNameService.findShopStandsByValueIds(params_set);
        if (shopStandsXr != null && XaUtil.isNotEmpty(shopStandsXr.getObject())) {
            shopStandardVos.addAll(shopStandsXr.getObject());//错误：java.lang.Object cannot be cast to java.util.Collection
        }

        //所有规格list转出Map
        ImmutableMap<Long, ShopStandardVo> map = com.google.common.collect.Maps.uniqueIndex(shopStandardVos, new Function<ShopStandardVo, Long>() {
            @Override
            public Long apply(ShopStandardVo shopStandardVo) {
                return shopStandardVo.getValueId();
            }
        });

        //把规格id变成规格名称
        //颜色:红色;尺寸:大号
        Map<Long, String> standVlaueMap = new HashedMap();
        long kkk = 0;
        for (OrderDetailVo obj : details) {
            String str = obj.getStandardValues();
            List<String> stands = new ArrayList<>();
            for (int jj = 0; jj < str.split(JConstant.SYMBOL_DOT).length; ++jj) {
                Long valueId = Long.parseLong(str.split(JConstant.SYMBOL_DOT)[jj]);
                ShopStandardVo vo = map.get(valueId);
                if (XaUtil.isNotEmpty(vo)) {
                    String ss = vo.getShop_stands_name() + JConstant.SYMBOL_COLON + vo.getShop_stands_value();
                    stands.add(ss);
                }
            }
            standVlaueMap.put(kkk, StringUtils.join(stands, JConstant.SYMBOL_SEMICOLON));//;
            kkk++;
        }

        order.setOrderTotalPirce(finalPirce);
        Order obj = orderRepository.save(order);
        //商品id集合
        Set<String> shopids = CollectionUtils.subCollectionSet(details, "shop_ProductSPU");
        Set<Long> shopidsLong = (Set<Long>) CollectionUtils.transformedCollectionForNumber(shopids, Long.class);
        //查询商品名称
        List<Shop> shops = shopRepository.findByIdInAndStatus(shopidsLong, XaConstant.Status.publish);
        Map<Long, Shop> shopMap = CollectionUtils.listToMap(shops.iterator(), new Function<Shop, Long>() {
            @Override
            public Long apply(Shop shop) {
                return shop.getId();
            }
        });
        {
            //如果订单保存成功，保存订单明细信息
            //更改库存量
            for (OrderDetailVo detail : details) {
                //设置价格
                detail.setProductOrderPrice(Double.parseDouble(shopMap.get(NumberUtils.toLong(detail.getShop_ProductSPU(), 0)).getShopProductPrice()));
                String uSql = "UPDATE tb_xa_shop SET shop_product_inventory = shop_product_inventory - ? WHERE id = ?";
                List param = Arrays.asList(detail.getProductNum(), detail.getShop_ProductSPU());
                this.update(uSql, param);
            }

            //订单明细
            StringBuffer sql = new StringBuffer();
            String dateStr = DateUtils.getToDayStr();
            sql.append("insert into tb_xa_order_detail(create_time,order_no,shop_productspu,product_num,standard_values,product_order_price,shop_original_price,shop_name,shop_url) values ");
            for (int i = 0; i < details.size(); i++) {
                Long productNum = details.get(i).getProductNum();
                String standVals = standVlaueMap.get(Long.parseLong(i + ""));
                Double price = details.get(i).getProductOrderPrice();//购买的价格，可能是原价，可能是优惠价格
                Double originalPrice = details.get(i).getShopOriginalPrice();
                sql.append("(").append(Sql(dateStr)).append(",")
                        .append(Sql(obj.getOrderNo())).append(",")
                        .append(Sql(details.get(i).getShop_ProductSPU())).append(",")
                        .append(productNum).append(",")
                        .append(Sql(standVals)).append(",") //颜色:红色;尺寸:大号
                        .append(price + "").append(",") //价格
                        .append(originalPrice + "").append(",") //原价
                        .append("(SELECT tb_xa_shop.shop_product_name FROM tb_xa_shop WHERE tb_xa_shop.id = " + details.get(i).getShop_ProductSPU() + ")").append(",")
                        .append("(SELECT tb_xa_shop.shop_product_pic_urls FROM tb_xa_shop WHERE tb_xa_shop.id = " + details.get(i).getShop_ProductSPU() + ")")
                        .append(")");
                sql.append("");
                if (i != details.size() - 1) {
                    sql.append(",");
                }
            }
            this.update(sql.toString());

            //如果是购物车下单，成功后清除购物车数据
            if (XaUtil.isNotEmpty(carIds)) {
                //DELETE FROM tb_xa_shopcar WHERE id IN (1,2)
                String[] ids = carIds.replaceAll(JConstant.SYMBOL_DOT_CN, JConstant.SYMBOL_DOT).split(JConstant.SYMBOL_DOT);
                StringBuffer delSql = new StringBuffer("DELETE FROM tb_xa_shopcar WHERE id IN ");
                for (int i = 0; i < ids.length; i++) {
                    if (i == 0) {
                        delSql.append("(");
                    }
                    delSql.append(Long.valueOf(ids[i]));
                    if (i != ids.length - 1) {
                        delSql.append(",");
                    }
                    if (i == ids.length - 1) {
                        delSql.append(")");
                    }
                }
                this.update(delSql.toString(), null);
            }
        }

        List<ShopVo> vos = new ArrayList<ShopVo>();
        for (Shop shop : shops) {
            ShopVo vo = new ShopVo();
            vo.setShopProductName(shop.getShopProductName());
            vo.setId(shop.getId());
            vo.setShopProductInventory(shop.getShopProductInventory());
            vos.add(vo);
        }

        xr.setObject(JSON.parseObject(JSON.toJSONString(obj), OrderVo.class));
        xr.getObject().setId(obj.getId());
        xr.getObject().setGoodsTotalPrices(order.getGoodsTotalPrices());//商品总价
        xr.getObject().setOrderTotalPirce(finalPirce);//订单总价
        xr.getObject().setShopVo(vos);

        return xr;
    }

    //取消订单
    @Override
    public XaResult<OrderVo> cancelOrder(String orderNo) throws BusinessException {
        XaResult<OrderVo> xr = new XaResult<OrderVo>();
        Order order = orderRepository.findByOrderNoAndStatusNot(orderNo, XaConstant.Status.delete);
        if (XaUtil.isEmpty(order)) {
            xr.error("该订单不存在！");
            return xr;
        }
        if (Integer.parseInt(order.getOrderState()) != JConstant.OrderStatus.UN_PAY) {
            xr.error("只有待付款的订单才能取消！当前状态:(" + order.getOrderState() + ")");
            return xr;
        }
        order.setOrderState(JConstant.OrderStatus.CLOSE_TRADE + "");
        order.setOrder_Dead_DateTime(DateUtils.getToDayStr());
        order = orderRepository.save(order);
        //取消订单(1:积分、亲币归还 2:库存归还)

        //亲币归还
        makeMoneyTableService.saveMakeMoneyRecord(order.getUserId(), JConstant.ConsumeOrMakeMoney.MakeMoney, order.getDeducted_money(), JConstant.IntegralTypeEnum.CONSUME_CANCLE.getIndex());

        //库存归还
        //1：普通商品  2:兑换商品  3：玩 /达人/作品/艺术品   51:住； 52:机构参观  53：旅游/游学     62:家政护理; 63:医疗服务|医疗康复; 64:护理培训|培训义工
        if (Integer.parseInt(order.getOrderType()) == JConstant.Order_CommentType.GOODS) {
            //普通商品
            List<OrderDetail> orderDetails = orderDetailRepository.findByOrderNoAndStatusNot(orderNo, XaConstant.Status.delete);
            //修改库存;并返回所有修改后台的商品集合
            List<Shop> shopList = shopService.updateShops(orderDetails).getObject();
        } else if (Integer.parseInt(order.getOrderType()) == JConstant.Order_CommentType.ARTWORK) {
            //  3：玩 /达人/作品/艺术品--------------
            Long orderServiceNum = order.getService_num();
            Long objId = order.getService_object_id();
            AutherWorksTableVo worksVo = autherWorksTableService.findOne(objId).getObject();
            worksVo.setWorksInventory((worksVo.getWorksInventory() + orderServiceNum));
            autherWorksTableService.updateModel(JSON.parseObject(JSON.toJSONString(worksVo), AutherWorksTable.class));
        } else if (Integer.parseInt(order.getOrderType()) == JConstant.Order_CommentType.TOUR) {
            //  53：旅游/游学--------------
            //不用处理
        } else if (Integer.parseInt(order.getOrderType()) == JConstant.Order_CommentType.HOURSE) {
            // 51:住
            //// TODO:dz 2016/12/28 酒店 不用考虑库存
            Long orderServiceNum = order.getService_num();
            Long objId = order.getService_object_id();
//            InsHotelRoomsTableVo roomVo = insHotelRoomsTableService.findOne(objId).getObject();
//            roomVo.setHotelRooms_Inventory((int) (roomVo.getHotelRooms_Inventory().longValue() + orderServiceNum));
//            insHotelRoomsTableService.updateModel(JSON.parseObject(JSON.toJSONString(roomVo), InsHotelRoomsTable.class));
        } else if (Integer.parseInt(order.getOrderType()) == JConstant.Order_CommentType.SERVICE_NURSE_TRANING) {
            //64:护理培训|培训义工
            Long orderServiceNum = order.getService_num();
            Long objId = order.getService_object_id();
            ServiceNurseTrainingVo traVo = nurseTrainingService.findOne(objId).getObject();
            traVo.setQuantityInventory((int) (traVo.getQuantityInventory().longValue() + orderServiceNum));
            nurseTrainingService.updateModel(JSON.parseObject(JSON.toJSONString(traVo), ServiceNurseTraining.class));
        }
        xr.setObject(JSON.parseObject(JSON.toJSONString(order), OrderVo.class));
        xr.getObject().setId(order.getId());
        return xr;
    }

    //确认收货
    @Override
    public XaResult<OrderVo> cofirmRevice(String orderNo) throws BusinessException {
        XaResult<OrderVo> xr = new XaResult<OrderVo>();
        Order obj = orderRepository.findByOrderNoAndStatusNot(orderNo, XaConstant.Status.delete);
        if (XaUtil.isEmpty(obj)) {
            xr.error("该订单不存在！");
            return xr;
        }
        if (Integer.parseInt(obj.getOrderState()) != JConstant.OrderStatus.UN_CONSIGNEE) {
            xr.error("只有待收货的订单才能确认收货！");
            return xr;
        }
        if (!(Integer.parseInt(obj.getOrderType()) == JConstant.Order_CommentType.GOODS
                || Integer.parseInt(obj.getOrderType()) == JConstant.Order_CommentType.GOODS_EXCHANGE
                || Integer.parseInt(obj.getOrderType()) == JConstant.Order_CommentType.ARTWORK)) {
            xr.error("只有商品订单才能确认收货!");
            return xr;
        }
        obj.setOrderState(JConstant.OrderStatus.UN_COMMENT + "");
        obj = orderRepository.save(obj);
        xr.setObject(JSON.parseObject(JSON.toJSONString(obj), OrderVo.class));
        xr.getObject().setId(obj.getId());
        return xr;
    }

    //获取订单
    @Override
    public Order getOrder(String orderNo) throws BusinessException {
        return orderRepository.findByOrderNoAndStatusNot(orderNo, XaConstant.Status.delete);
    }

    //查询订单详情
    @Override
    public XaResult<OrderVo> findDetail(String orderNo) throws BusinessException {
        Order obj = orderRepository.findByOrderNoAndStatusNot(orderNo, XaConstant.Status.delete);
        if (XaUtil.isEmpty(obj)) {
            throw new BusinessException(XaConstant.Message.object_not_find);
        }
        List<OrderDetail> orderDetails = orderDetailRepository.findByOrderNoInAndStatusNot(Lists.newArrayList(obj.getOrderNo()), XaConstant.Status.delete);

        XaResult<OrderVo> xr = new XaResult<>();
        xr.setObject(JSON.parseObject(JSON.toJSONString(obj), OrderVo.class));
        xr.getObject().setOrderDetails(JSON.parseArray(JSON.toJSONString(orderDetails), OrderDetailVo.class));
        return xr;
    }

    @Override
    public XaResult<OrderVo> findOrderInfoByOrderNo(String orderNO) throws BusinessException {
        XaResult<OrderVo> xr = new XaResult<OrderVo>();
        Order obj = orderRepository.findByOrderNoAndStatusNot(orderNO, XaConstant.Status.delete);
        if (XaUtil.isEmpty(obj)) {
            xr.error(XaConstant.Message.object_not_find);
            throw new BusinessException(XaConstant.Message.object_not_find);
        } else {
            xr.setObject(JSON.parseObject(JSON.toJSONString(obj), OrderVo.class));
            xr.getObject().setId(obj.getId());
            int orderType = Integer.parseInt(obj.getOrderType());
            if (orderType == JConstant.Order_CommentType.GOODS) {//1

                List<OrderDetail> orderDetails = orderDetailRepository.findByOrderNoAndStatusNot(orderNO, XaConstant.Status.delete);
                String shopNameStr = ":";
                if (XaUtil.isNotEmpty(orderDetails)) {
                    Set<String> set = CollectionUtils.subCollectionSet(orderDetails, "shopName");
                    shopNameStr += StringUtils.join(set.iterator(), JConstant.SYMBOL_DOT);
                } else {
                    shopNameStr = "";
                }
                xr.getObject().setOrderName("普通商品" + shopNameStr);
            } else if (orderType == JConstant.Order_CommentType.GOODS_EXCHANGE) {//2
                xr.getObject().setOrderName("兑换商品:" + exchangeProductsService.findOne(obj.getService_object_id()).getObject().getProductName());
            } else if (orderType == JConstant.Order_CommentType.ARTWORK) {//3
                xr.getObject().setOrderName("达人作品:" + autherWorksTableService.findOne(obj.getService_object_id()).getObject().getWorksName());
            } else if (orderType == JConstant.Order_CommentType.HOURSE) {//51
                xr.getObject().setOrderName("住:" + insHotelRoomsTableService.findOne(obj.getService_object_id()).getObject().getHotelRooms_Name());
            } else if (orderType == JConstant.Order_CommentType.INSTIBUTION_VISITING) {//52
                xr.getObject().setOrderName("机构参观:" + institutionService.findOne(obj.getService_object_id()).getObject().getInstitution_Name());
            } else if (orderType == JConstant.Order_CommentType.TOUR) {//53
                xr.getObject().setOrderName("旅游:" + travelTableService.findOne(obj.getService_object_id()).getObject().getTravelItemName());
            } else if (orderType == JConstant.Order_CommentType.SERVICE_NURSE_TRANING) {//64
                xr.getObject().setOrderName("护理培训:" + nurseTrainingService.findOne(obj.getService_object_id()).getObject().getNurseTraining_Name());
            }
        }
        return xr;
    }

    /**
     * 支付成功后处理订单状态
     *
     * @param orderNo 服务订单-订单号
     * @param price   支付总价格
     * @param queryId 支付宝交易号(退款用)
     * @return
     */
    @Override
    public String modifyOrder(String orderNo, String price, String queryId, int payType) {
        try {
            Order order = orderRepository.findByOrderNoAndStatusNot(orderNo,
                    XaConstant.Status.delete);
            if (XaUtil.isNotEmpty(order) && Integer.parseInt(order.getOrderState()) == JConstant.OrderStatus.PAYED) {//已经支付
                return "0001"; // 0001代表已经支付过
            }

            if (payType == JConstant.PayType.WALLET) {//钱包支付 修改订单 1：账号余额修改 2：钱包交易记录增加
                //钱包支付
                UserVo userVo = userService.findOne(order.getUserId()).getObject();
                walletTradeRecordService.walletPaySucessSaveRecord(userVo, order);
            }

            order.setPaymentKind(payType);
            order.setQueryId(queryId);
            if (XaUtil.isNotEmpty(order) && Integer.parseInt(order.getOrderState()) == JConstant.OrderStatus.UN_PAY) {//未支付
                order.setOrderState(JConstant.OrderStatus.PAYED + "");
                order.setOrder_PAY_DateTime(DateUtils.getStrDate(new Date(), DateUtils.YYYYMMDDHHMMSS));
                orderRepository.save(order);

                // 发送短信通知
                if (Integer.parseInt(order.getOrderState()) == JConstant.Order_CommentType.SERVICE_NURSE_TRANING) { //护理培训|培训义工
                    // TODO:dz 2017/1/10
                    //库存量减少(服务订单库存减少)
                    //String updateSql = "UPDATE tb_xa_nursetraining nurs LEFT JOIN tb_xa_order orders ON nurs.id = orders.service_object_id SET nurs.quantity_inventory = nurs.quantity_inventory - orders.service_num WHERE orders.order_no = ?";
                    //int updateCount = this.update(updateSql,Arrays.asList(new Object[]{orderNo}));
//                    List<Object> params = new ArrayList<Object>();
//                    String sql = "SELECT ord.order_no, dom.merchant_name,dom.merchant_service_name FROM tb_xa_order ord LEFT JOIN tb_xa_medicalservice dom ON ord.service_object_id = dom.id  WHERE ord.order_no = ?";
//                    params.add(orderNo);
//                    List<Object[]> objs = this.queryParams(sql.toString(), null, null,
//                            params);
//                    if (XaUtil.isNotEmpty(objs) && objs.size() == 1) {
//                        HashMap<String, Object> result = YuntongxunSmsUtil.sendMessege(order.getService_phone(), JConstant.ShortMessageType.SERVICE_NURSE_TRANING_SM,
//                                //培训公司; 培训项目
//                                new String[]{(String) objs.get(0)[1], (String) objs.get(0)[2]});
//                        if ("000000".equals((String) result.get("statusCode"))) {
//                            LOGGER.error("医疗服务|医疗康复:短信发送成功");
//                        } else {
//                            LOGGER.error("医疗服务|医疗康复:短信发送失败:" + result);
//                        }
//                    }
                } else if (Integer.parseInt(order.getOrderState()) == JConstant.Order_CommentType.INSTIBUTION_VISITING) {//机构参观 INSTIBUTION_VISITING
                    //机构参观 成功
                    List<Object> params = new ArrayList<Object>();
                    String sql = "SELECT ord.order_no, ins.institution_tel_phone , ins.institution_name  FROM tb_xa_order ord LEFT JOIN tb_xa_institution ins ON ord.service_object_id = ins.id WHERE ord.order_no = ? ORDER BY ord.order_no ASC LIMIT 0,1";
                    params.add(orderNo);
                    List<Object[]> objs = this.queryParams(sql.toString(), null, null,
                            params);
                    if (XaUtil.isNotEmpty(objs) && objs.size() == 1) {
                        HashMap<String, Object> result = YuntongxunSmsUtil.sendMessege(order.getService_phone(), JConstant.ShortMessageType.SERVICE_COMMON_SM,
                                //参观的机构; 机构电话
                                new String[]{(String) objs.get(0)[1], (String) objs.get(0)[2]});
                        if ("000000".equals((String) result.get("statusCode"))) {
                            LOGGER.error("机构参观:短信发送成功");
                        } else {
                            LOGGER.error("机构参观:短信发送失败:" + result);
                        }
                    }
                } else if (Integer.parseInt(order.getOrderState()) == JConstant.Order_CommentType.HOURSE) {//房子 HOURSE
                    //房子酒店预订 成功
                    List<Object> params = new ArrayList<Object>();
                    String sql = "SELECT ord.order_no, ins.institution_tel_phone , ins.institution_name  FROM tb_xa_order ord LEFT JOIN tb_xa_institution ins ON ord.service_object_id = ins.id WHERE ord.order_no = ? ORDER BY ord.order_no ASC LIMIT 0,1";
                    params.add(orderNo);
                    List<Object[]> objs = this.queryParams(sql.toString(), null, null,
                            params);
                    if (XaUtil.isNotEmpty(objs) && objs.size() == 1) {
                        HashMap<String, Object> result = YuntongxunSmsUtil.sendMessege(order.getService_phone(), JConstant.ShortMessageType.SERVICE_COMMON_SM,
                                //参观的机构; 机构电话
                                new String[]{(String) objs.get(0)[1], (String) objs.get(0)[2]});
                        if ("000000".equals((String) result.get("statusCode"))) {
                            LOGGER.error("酒店(养护院):短信发送成功");
                        } else {
                            LOGGER.error("酒店(养护院):短信发送失败:" + result);
                        }
                    }
                } else if (Integer.parseInt(order.getOrderState()) == JConstant.Order_CommentType.TOUR) {//旅游/游学 TOUR
                    //旅游/游学门票订购 成功
                    List<Object> params = new ArrayList<Object>();
                    String sql = "SELECT ord.order_no, travel.travel_item_telephone , travel.travel_item_name  FROM tb_xa_order ord LEFT JOIN tb_xa_traveltable travel ON ord.service_object_id = travel.id WHERE ord.order_no = ? ORDER BY ord.order_no ASC LIMIT 0,1";
                    params.add(orderNo);
                    List<Object[]> objs = this.queryParams(sql.toString(), null, null,
                            params);
                    if (XaUtil.isNotEmpty(objs) && objs.size() == 1) {
                        HashMap<String, Object> result = YuntongxunSmsUtil.sendMessege(order.getService_phone(), JConstant.ShortMessageType.SERVICE_COMMON_SM,
                                //景点名称; 景点电话
                                new String[]{(String) objs.get(0)[1], (String) objs.get(0)[2]});
                        if ("000000".equals((String) result.get("statusCode"))) {
                            LOGGER.error("旅游/游学门票订购:短信发送成功");
                        } else {
                            LOGGER.error("旅游/游学门票订购:短信发送失败:" + result);
                        }
                    }
                }
                return "0000"; // 支付成功后状态修改成功
            }
        } catch (Exception e) {
            return "0002"; // 支付成功后状态修改失败
        }
        return null;
    }

    //修改订单退款信息
    @Override
    public String modifyOrderRefund(String orderNo, Integer refundStatus, int payType) {
        try {
            Order order = null;
            if (payType == JConstant.PayType.WXPAY) {
                order = orderRepository.findByRefuOrderNoAndStatusNot(orderNo, XaConstant.Status.delete);
            } else if (payType == JConstant.PayType.WALLET) {
                order = orderRepository.findByOrderNoAndStatusNot(orderNo, XaConstant.Status.delete);
            } else {
                order = orderRepository.findByQueryIdAndStatusNot(orderNo, XaConstant.Status.delete);
            }
            if (XaUtil.isNotEmpty(order)) {
                order.setRefundStatus(refundStatus);
                //更改退款状态
                if (refundStatus.intValue() == JConstant.OrderRefundStatus.REFUND_SUCCESS) {

                    if (payType == JConstant.PayType.WALLET) {//钱包支付退款
                        //1：账号余额返还 2：交易记录
                        UserVo userVo = userService.findOne(order.getUserId()).getObject();
                        walletTradeRecordService.walletPayRefundSaveRecord(userVo, order);
                    }

                    //退货和退款退还逻辑相同
                    /**
                     * @see  cancelorder
                     */
                    //退货完成，1:库存归还；2:积分/亲币要归还
                    //================================================================================================================================================
                    //亲币归还
                    makeMoneyTableService.saveMakeMoneyRecord(order.getUserId(), JConstant.ConsumeOrMakeMoney.MakeMoney, order.getDeducted_money(), JConstant.IntegralTypeEnum.CONSUME_CANCLE.getIndex());
                    //库存归还
                    //1：普通商品  2:兑换商品  3：玩 /达人/作品/艺术品   51:住； 52:机构参观  53：旅游/游学     62:家政护理; 63:医疗服务|医疗康复; 64:护理培训|培训义工
                    if (Integer.parseInt(order.getOrderType()) == JConstant.Order_CommentType.GOODS) {
                        //普通商品
                        List<OrderDetail> orderDetails = orderDetailRepository.findByOrderNoAndStatusNot(orderNo, XaConstant.Status.delete);
                        //修改库存;并返回所有修改后台的商品集合
                        shopService.updateShops(orderDetails);
                    } else if (Integer.parseInt(order.getOrderType()) == JConstant.Order_CommentType.ARTWORK) {
                        //  3：玩 /达人/作品/艺术品--------------
                        Long orderServiceNum = order.getService_num();
                        Long objId = order.getService_object_id();
                        AutherWorksTableVo worksVo = autherWorksTableService.findOne(objId).getObject();
                        worksVo.setWorksInventory((worksVo.getWorksInventory() + orderServiceNum));
                        autherWorksTableService.updateModel(JSON.parseObject(JSON.toJSONString(worksVo), AutherWorksTable.class));
                    } else if (Integer.parseInt(order.getOrderType()) == JConstant.Order_CommentType.TOUR) {
                        //  53：旅游/游学--------------
                        //不用处理
                    } else if (Integer.parseInt(order.getOrderType()) == JConstant.Order_CommentType.HOURSE) {
                        // 51:住
                        //// TODO:dz 2016/12/28 酒店 不用考虑库存
                        Long orderServiceNum = order.getService_num();
                        Long objId = order.getService_object_id();
                        //InsHotelRoomsTableVo roomVo = insHotelRoomsTableService.findOne(objId).getObject();
                        //roomVo.setHotelRooms_Inventory((int) (roomVo.getHotelRooms_Inventory().longValue() + orderServiceNum));
                        //insHotelRoomsTableService.updateModel(JSON.parseObject(JSON.toJSONString(roomVo), InsHotelRoomsTable.class));
                    } else if (Integer.parseInt(order.getOrderType()) == JConstant.Order_CommentType.SERVICE_NURSE_TRANING) {
                        //64:护理培训|培训义工
                        Long orderServiceNum = order.getService_num();
                        Long objId = order.getService_object_id();
                        ServiceNurseTrainingVo traVo = nurseTrainingService.findOne(objId).getObject();
                        traVo.setQuantityInventory((int) (traVo.getQuantityInventory().longValue() + orderServiceNum));
                        nurseTrainingService.updateModel(JSON.parseObject(JSON.toJSONString(traVo), ServiceNurseTraining.class));
                    }
                    //================================================================================================================================================

                    order.setOrderState(JConstant.OrderStatus.CLOSE_TRADE + "");//退款成功-->交易关闭
                    order.setOrder_Dead_DateTime(DateUtils.getToDayStr());
                }
                orderRepository.save(order);
            } else {
                LOGGER.info("订单不存在!");
            }
            return "0000"; // 支付成功后状态修改成功
        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
            return "0002"; // 支付成功后状态修改失败
        }
    }

    @Override
    public XaResult<List<OrderVo>> findListEQStatusByFilter(
            Integer status, Map<String, Object> filterParams, Pageable pageable)
            throws BusinessException {
        throw new BusinessException(XaConstant.Message.error_method_no_impl);
    }

    @Override
    public XaResult<List<OrderVo>> getOrders(Long userId, String orderState, String orderType, Integer begin, Integer count) throws BusinessException {
        Map<String, Object> filterParams = null;
        if (XaUtil.isEmpty(orderState) && XaUtil.isEmpty(orderType)) {
            filterParams = WebUitl.getParametersStartingWith("{'search_EQ_userId':'" + userId + "'}", "search_");
        } else {
            if (XaUtil.isNotEmpty(orderState) && XaUtil.isNotEmpty(orderType)) {
                filterParams = WebUitl.getParametersStartingWith(
                        "{'search_IN_orderState':'" + Arrays.asList(orderState.split(JConstant.SYMBOL_DOT)) + "'" +
                                ",'search_IN_orderType':'" + Arrays.asList(orderType.split(JConstant.SYMBOL_DOT)) + "'" +
                                ",'search_EQ_userId':'" + userId + "'}", "search_");
            } else if (XaUtil.isNotEmpty(orderState)) {
                filterParams = WebUitl.getParametersStartingWith(
                        "{'search_IN_orderState':'" + Arrays.asList(orderState.split(JConstant.SYMBOL_DOT)) + "'" +
                                ",'search_EQ_userId':'" + userId + "'}", "search_");
            } else {
                filterParams = WebUitl.getParametersStartingWith(
                        "{'search_IN_orderType':'" + Arrays.asList(orderType.split(JConstant.SYMBOL_DOT)) + "'" +
                                ",'search_EQ_userId':'" + userId + "'}", "search_");
            }
        }

        Pageable pageable = WebUitl.buildPageRequest(begin, count, "[{property:'createTime',direction:'DESC'}]");
        Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);
        filters.put("status", new SearchFilter("status", Operator.EQ, XaConstant.Status.valid));
        Page<Order> page = orderRepository.findAll(DynamicSpecifications
                .bySearchFilter(filters.values(), Order.class), pageable);
        XaResult<List<OrderVo>> xr = new XaResult<List<OrderVo>>();
        xr.setObject(JSON.parseArray(JSON.toJSONString(page.getContent()), OrderVo.class));

        for (int i = 0; i < page.getContent().size(); i++) {
            xr.getObject().get(i).setId(page.getContent().get(i).getId());
        }
        Set<String> orderNos = com.web.webstart.base.util.CollectionUtils.subCollectionSet(page.getContent(), "orderNo");

        //查询所有订单详情
        List<OrderDetail> orderDetails = XaUtil.isNotEmpty(orderNos) ? orderDetailRepository.findByOrderNoInAndStatusNot(orderNos, XaConstant.Status.delete) : null;
        Map<Long, Collection<OrderDetail>> map = null;
        if (XaUtil.isNotEmpty(orderDetails)) {
            map = com.web.webstart.base.util.CollectionUtils.listToMulMap(orderDetails.iterator(), new Function<OrderDetail, Long>() {
                @Override
                public Long apply(OrderDetail orderDetail) {
                    return Long.parseLong(orderDetail.getOrderNo());
                }
            }).asMap();
        }

        //拼装数据
        for (int j = 0; map != null && j < page.getContent().size(); j++) {
            Long orderNo = Long.parseLong(xr.getObject().get(j).getOrderNo());
            Collection col = map.get(orderNo);
            if (XaUtil.isNotEmpty(col)) {
                xr.getObject().get(j).setOrderDetails(Lists.newArrayList(col));
            }
        }
        return xr;
    }

    //测试Transactional;
    //http://blog.csdn.net/u013142781/article/details/50421904
    //http://blog.csdn.net/sdh870680601/article/details/50879753
    //http://blog.csdn.net/weitao233136/article/details/51841707
    // 事物失效的原因：http://www.cnblogs.com/edwinchen/p/4137707.html
    // 事物失效的原因：http://jinnianshilongnian.iteye.com/blog/1850432
    @Override
    public void testTransactionals() throws BusinessException {
        LOGGER.info("start testTransactionals.......");
        String sql = "UPDATE tb_xa_user SET memo = 'dazhi1' WHERE id = 1;";
        this.update(sql, null);
        repository.save(new User("18800004444"));
//        int bb = 1 / 0;
        String sql2 = "UPDATE tb_xa_user SET memo = 'dazhi2' WHERE id = 2;";
//        this.update(sql2, null);
        repository.save(new User("18800004445"));
        LOGGER.info("end testTransactionals.......");
    }

    /**
     * 获取订单有效时间
     * 订单有效期，目前暂设12小时
     *
     * @return
     */
    private String getOrderVilidatyDefault() {
        return DateUtils.calculateDate(DateUtils.getToDayStr(), "hour", 24 / 2);
    }
}
